/**
 * 二次封装前端本地存储localStorage与sessionStorage
 * https://blog.csdn.net/xu_yi_hang/article/details/135914250
 * https://www.mulingyuer.com/archives/880/
 */

import { AES_CBC_Encrypt } from "./crypto-util";

/** 存储类型 */
export type StorageType = "local" | "session";
/** 存储类配置参数 */
export type StorageOptions = {
  type?: StorageType;
  prefix?: string;
};

class LStorage {
  private storage: Storage;
  private prefix: string = "tc_";

  constructor(options: StorageOptions) {
    const { type, prefix } = options;
    switch (type) {
    case "local":
      this.storage = window.localStorage;
      break;
    case "session":
      this.storage = window.sessionStorage;
      break;
    default:
      this.storage = window.localStorage;
    }

    if (prefix) {
      this.prefix = prefix;
    }
  }

  /** 存储数据 */
  public setItem(key: string, value: any) {
    key = AES_CBC_Encrypt(this.prefix + key);
    if (typeof value === "string") {
      this.storage.setItem(key, value);
      return;
    }
    try {
      this.storage.setItem(key, JSON.stringify(value));
    } catch (error: any) {
      throw new Error("存储数据失败：" + error);
    }
  }

  /**
   * 获取数据
   * @param {string} key
   * @param {boolean} isJson
   * @returns {any}
   */
  public getItem<T>(key: string, isJson: boolean) {
    key = AES_CBC_Encrypt(this.prefix + key);
    const value = this.storage.getItem(key);
    if (!value) return null;

    if (!isJson) return value as T;
    try {
      return JSON.parse(value) as T;
    } catch (error: any) {
      throw new Error("存储数据获取失败：" + error);
    }
  }

  /** 删除数据 */
  public removeItem(key: string) {
    key = AES_CBC_Encrypt(this.prefix + key);
    this.storage.removeItem(key);
  }

  /** 清空数据 */
  public clear() {
    this.storage.clear();
  }
}

/** 实例化 */
const lLocal = new LStorage({ type: "local", prefix: "zmkm_gl_" });
const sLocal = new LStorage({ type: "session", prefix: "zmkm_gl_" });

export { LStorage, lLocal, sLocal };
